package com.ytxg.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ytxg.core.constant.DatabaseConsts;
import com.ytxg.dto.*;
import com.ytxg.mapper.*;
import com.ytxg.po.*;
import com.ytxg.service.IBookInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ytxg.util.resp.RestResp;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 小说信息 服务实现类
 * </p>
 *
 * @author YT_XG
 * @since 2023-12-09
 */
@Service
public class BookInfoServiceImpl extends ServiceImpl<BookInfoMapper, BookInfo> implements IBookInfoService {


    @Resource
    private BookChapterMapper bookChapterMapper;
    @Resource
    private BookContentMapper bookContentMapper;
    @Resource
    private BookInfoMapper bookInfoMapper;
    @Resource
    private BookCommentMapper bookCommentMapper;
    @Resource
    private UserInfoMapper userInfoMapper;


    @Override
    public RestResp<List<BookChapterRespDto>> listChapters(Long bookId) {
        // 我们要根据 book_id 查询章节列表
        // select * from book_chapter where book_id = '1431630596354977799' order by chapter_num asc
        // mybatis-plus 的条件构造器(QueryWrapper)来代替 sql
        // eq 代表等号   orderByAsc 代表 order by
        QueryWrapper<BookChapter> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq(DatabaseConsts.BookChapterTable.COLUMN_BOOK_ID, bookId)
        queryWrapper.eq("book_id", bookId)
                .orderByAsc("chapter_num");
        List<BookChapter> bookChapterList = bookChapterMapper.selectList(queryWrapper);

        LambdaQueryWrapper<BookChapter> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BookChapter::getBookId, bookId)
                .orderByAsc(BookChapter::getChapterNum);
        List<BookChapter> lambdaBookChapterList = bookChapterMapper.selectList(lambdaQueryWrapper);

        List<BookChapterRespDto> dtoList = new ArrayList<>();
        for (BookChapter bookChapter : lambdaBookChapterList) {
            BookChapterRespDto dto = BookChapterRespDto.builder().build();
            BeanUtils.copyProperties(bookChapter, dto);
            dtoList.add(dto);
        }

        List<BookChapterRespDto> bookChapterRespDtoList = bookChapterList.stream().map(
                bookChapter -> BookChapterRespDto.builder()
                        .id(bookChapter.getId())
                        .chapterName(bookChapter.getChapterName())
                        .isVip(bookChapter.getIsVip())

                        .bookId(bookChapter.getBookId())
                        .chapterNum(bookChapter.getChapterNum())
                        .chapterWordCount(bookChapter.getWordCount())
                        .chapterUpdateTime(bookChapter.getUpdateTime())
                        .build()   //  bookChapter  - > dto
        ).toList(); // List<BookChapterRespDto>

        return RestResp.ok(dtoList);  //
    }

    @Override
    public RestResp<BookContentAboutRespDto> getBookContentAbout(Long chapterId) {
        // 查询章节信息
        BookChapter bookChapter = bookChapterMapper.selectById(chapterId);
        BookChapterRespDto bookChapterDto = BookChapterRespDto.builder()
                .id(chapterId)
                .bookId(bookChapter.getBookId())
                .chapterNum(bookChapter.getChapterNum().intValue())
                .chapterName(bookChapter.getChapterName())
                .chapterWordCount(bookChapter.getWordCount())
                .chapterUpdateTime(bookChapter.getUpdateTime())
                .isVip(bookChapter.getIsVip().intValue())
                .build();

        // 查询章节内容
        // String content = bookContentCacheManager.getBookContent(chapterId);
        QueryWrapper<BookContent> contentQueryWrapper = new QueryWrapper<>();
        contentQueryWrapper.eq(DatabaseConsts.BookContentTable.COLUMN_CHAPTER_ID, chapterId)
                .last(DatabaseConsts.SqlEnum.LIMIT_1.getSql());
        BookContent bookContent = bookContentMapper.selectOne(contentQueryWrapper);
        String content = bookContent.getContent();

        // 查询小说信息
//        BookInfoRespDto bookInfo = bookInfoCacheManager.getBookInfo(bookChapter.getBookId());
        // 查询基础信息
        Long id = bookChapter.getBookId();
        BookInfo bookInfo = bookInfoMapper.selectById(id);
        // 查询首章ID
        QueryWrapper<BookChapter> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq(DatabaseConsts.BookChapterTable.COLUMN_BOOK_ID, id)
                .orderByAsc(DatabaseConsts.BookChapterTable.COLUMN_CHAPTER_NUM)
                .last(DatabaseConsts.SqlEnum.LIMIT_1.getSql());
        BookChapter firstBookChapter = bookChapterMapper.selectOne(queryWrapper);
        // 组装响应对象
        BookInfoRespDto bookInfoDto = BookInfoRespDto.builder()
                .id(bookInfo.getId())
                .bookName(bookInfo.getBookName())
                .bookDesc(bookInfo.getBookDesc())
                .bookStatus(bookInfo.getBookStatus())
                .authorId(bookInfo.getAuthorId())
                .authorName(bookInfo.getAuthorName())
                .categoryId(bookInfo.getCategoryId())
                .categoryName(bookInfo.getCategoryName())
                .commentCount(bookInfo.getCommentCount())
                .firstChapterId(firstBookChapter.getId())
                .lastChapterId(bookInfo.getLastChapterId())
                .picUrl(bookInfo.getPicUrl())
                .visitCount(bookInfo.getVisitCount())
                .wordCount(bookInfo.getWordCount())
                .build();

        // 组装数据并返回
        return RestResp.ok(BookContentAboutRespDto.builder()
                .bookInfo(bookInfoDto)
                .chapterInfo(bookChapterDto)
                .bookContent(content)
                .build());

    }

    @Override
    public RestResp<BookInfoRespDto> getBookById(Long bookId) {
        // 查询基础信息
        BookInfo bookInfo = bookInfoMapper.selectById(bookId);
        // 查询首章ID
        QueryWrapper<BookChapter> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq(DatabaseConsts.BookChapterTable.COLUMN_BOOK_ID, bookId)
                .orderByAsc(DatabaseConsts.BookChapterTable.COLUMN_CHAPTER_NUM)
                .last(DatabaseConsts.SqlEnum.LIMIT_1.getSql());
        BookChapter firstBookChapter = bookChapterMapper.selectOne(queryWrapper);
        // 组装响应对象
        BookInfoRespDto dto = BookInfoRespDto.builder()
                .id(bookInfo.getId())
                .bookName(bookInfo.getBookName())
                .bookDesc(bookInfo.getBookDesc())
                .bookStatus(bookInfo.getBookStatus())
                .authorId(bookInfo.getAuthorId())
                .authorName(bookInfo.getAuthorName())
                .categoryId(bookInfo.getCategoryId())
                .categoryName(bookInfo.getCategoryName())
                .commentCount(bookInfo.getCommentCount())
                .firstChapterId(firstBookChapter.getId())
                .lastChapterId(bookInfo.getLastChapterId())
                .picUrl(bookInfo.getPicUrl())
                .visitCount(bookInfo.getVisitCount())
                .wordCount(bookInfo.getWordCount())
                .build();
        return RestResp.ok(dto);
    }

    /**
     * 点击榜单
     *
     * @return
     */
    @Override
    public RestResp<List<BookRankRespDto>> getBookOrdByVisit() {
        List<BookRankRespDto> bookRankRespDtoList = new ArrayList<>();//返回列表
        //根据浏览量排序
        LambdaQueryWrapper<BookInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(BookInfo::getVisitCount);

        //获取数据
        List<BookInfo> bookInfos = bookInfoMapper.selectList(lambdaQueryWrapper);
        //每一个数据拷贝到Dto，并加到返回列表
        for (BookInfo bookInfo : bookInfos) {
            BookRankRespDto oneDto = BookRankRespDto.builder()
                    .build();
            BeanUtils.copyProperties(bookInfo, oneDto);
            bookRankRespDtoList.add(oneDto);
        }

        return RestResp.ok(bookRankRespDtoList);
    }

    /**
     * 获取最新榜单
     *
     * @return
     */
    @Override
    public RestResp<List<BookRankRespDto>> getBookRank() {

        LambdaQueryWrapper<BookInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(BookInfo::getCreateTime);

        List<BookInfo> bookInfos = bookInfoMapper.selectList(lambdaQueryWrapper);

        List<BookRankRespDto> bookRankRespDtoList = new ArrayList<>();
        for (BookInfo bookInfo : bookInfos) {
            BookRankRespDto oneDto = BookRankRespDto.builder().build();
            BeanUtils.copyProperties(bookInfo, oneDto);
            bookRankRespDtoList.add(oneDto);
        }

        return RestResp.ok(bookRankRespDtoList);
    }

    /**
     * 更新榜单
     *
     * @return
     */
    @Override
    public RestResp<List<BookRankRespDto>> getBookUpdateRank() {
        //返回列表
        List<BookRankRespDto> bookRankRespDtoList = new ArrayList<>();
        //根据更新时间排序
        LambdaQueryWrapper<BookInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(BookInfo::getUpdateTime).last("limit 10");
        //获取数据
        List<BookInfo> bookInfos = bookInfoMapper.selectList(lambdaQueryWrapper);
        for (BookInfo bookInfo : bookInfos) {
            BookRankRespDto oneDto = BookRankRespDto.builder().build();
            BeanUtils.copyProperties(bookInfo, oneDto);
            bookRankRespDtoList.add(oneDto);
        }

        return RestResp.ok(bookRankRespDtoList);
    }

    /**
     * 增加点击量
     *
     * @param id
     */
    @Override
    public void addVisit(long id) {
        //查询id==id
        LambdaQueryWrapper<BookInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BookInfo::getId, id);

        //数据库浏览量加一
        BookInfo bookInfo = bookInfoMapper.selectById(id);
        bookInfo.setVisitCount(bookInfo.getVisitCount() + 1);
        bookInfoMapper.update(bookInfo, lambdaQueryWrapper);

    }

    /**
     * 同类推荐
     *
     * @param bookId
     * @return
     */
    @Override
    public RestResp<List<BookInfoRespDto>> getRecList(Long bookId) {
        List<BookInfoRespDto> respDtos = new ArrayList<>();//最终返回列表

        //查询本id的书的信息
        LambdaQueryWrapper<BookInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BookInfo::getId, bookId);
        BookInfo bookInfo = bookInfoMapper.selectOne(lambdaQueryWrapper);

        //查询与本id相同类型的书的信息
        Long categoryId = bookInfo.getCategoryId();
        LambdaQueryWrapper<BookInfo> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper1.eq(BookInfo::getCategoryId, categoryId)
                .orderByDesc(BookInfo::getVisitCount)
                .ne(BookInfo::getId, bookId)
                .last("limit 5");
        List<BookInfo> bookInfos = bookInfoMapper.selectList(lambdaQueryWrapper1);
        //封装
        for (BookInfo b : bookInfos) {
            BookInfoRespDto bookInfoRespDto = toResult(b);
            respDtos.add(bookInfoRespDto);
        }


        return RestResp.ok(respDtos);
    }

    @Override
    public RestResp<BookCommentDto> getNewestList(Long bookId) {
        List<BookCommentTxtDto> bookCommentTxtDtos = new ArrayList();//评论内容列表
        //根据id找评论
        LambdaQueryWrapper<BookComment> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BookComment::getBookId, bookId);
        List<BookComment> bookComments = bookCommentMapper.selectList(lambdaQueryWrapper);

        //转化
        for (BookComment bookComment : bookComments) {
            LambdaQueryWrapper<UserInfo> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper1.eq(UserInfo::getId, bookComment.getUserId());
            UserInfo userInfo = userInfoMapper.selectOne(lambdaQueryWrapper1);
            BookCommentTxtDto temp = BookCommentTxtDto.builder()
                    .commentContent(bookComment.getCommentContent())
                    .commentTime(bookComment.getCreateTime())
                    .commentUser(userInfo.getNickName())
                    .id(bookComment.getId())
                    .commentUserId(bookComment.getUserId())
                    .commentUserPhoto(userInfo.getUserPhoto())
                    .build();
            bookCommentTxtDtos.add(temp);
        }


        //创建返回类
        BookCommentDto build = BookCommentDto.builder().build();
        //设置总数
        build.setCommentTotal(Integer.toUnsignedLong(bookComments.size()));
        build.setComments(bookCommentTxtDtos);

        return RestResp.ok(build);

    }

    @Override
    public RestResp getBookAbout(Long bookId) {

        //获取id书籍信息
        BookInfo bookInfo = bookInfoMapper.selectOne(new LambdaQueryWrapper<BookInfo>().eq(BookInfo::getId, bookId));

        List<BookChapter> bookChapters = bookChapterMapper.selectList(new LambdaQueryWrapper<BookChapter>().eq(BookChapter::getBookId, bookId));
        //获取最新章节信息
        BookChapter bookChapter = bookChapterMapper.selectOne(new LambdaQueryWrapper<BookChapter>().eq(BookChapter::getId, bookInfo.getLastChapterId()));

        BookChapterRespDto build = BookChapterRespDto.builder()
                .chapterUpdateTime(bookChapter.getUpdateTime())
                .chapterWordCount(bookChapter.getWordCount())
                .build();
        BeanUtils.copyProperties(bookChapter, build);

        BookLastChapterDto build1 = BookLastChapterDto.builder()
                .chapterTotal(Integer.toUnsignedLong(bookChapters.size()))
                .chapterInfo(build)
                .contentSummary(build.getChapterName())
                .build();
        return RestResp.ok(build1);
    }

    @Override
    public RestResp getList(Integer workDirection) {
        List<BookInfo> bookInfos = bookInfoMapper.selectList(new QueryWrapper<BookInfo>()
                .orderByAsc("category_id")
                .select("distinct category_id,category_name")
                .lambda()
                .eq(BookInfo::getWorkDirection, workDirection)
        );


        List<BookListDto> resultList = new ArrayList<>();
        for (BookInfo bookInfo : bookInfos) {
            BookListDto temp = BookListDto.builder()
                    .name(bookInfo.getCategoryName())
                    .id(bookInfo.getCategoryId())
                    .build();
            resultList.add(temp);
        }
        return RestResp.ok(resultList);
    }


    /**
     * 将bookInfo转化成bookInfoRespDto
     *
     * @param bookInfo
     * @return
     */
    public BookInfoRespDto toResult(BookInfo bookInfo) {
        BookInfoRespDto build = BookInfoRespDto.builder().build();
        BeanUtils.copyProperties(bookInfo, build);
        return build;
    }
}
